#ifndef LOGGER_H_INCLUDED
#define LOGGER_H_INCLUDED

#include <Ape/Object.h>
#include <Ape/String.h>
#include <Ape/DateTime.h>
#include <Ape/IO/FS/RegularFile.h>

#include <MultiplexD/WorkerModel/MultiplexLetter.h>
#include <MultiplexD/WorkerModel/MultiplexWorker.h>
/*
#define LOG(sMsg, ltSeverity) \
	{ \
		if (false) { Ape::IO::StdOut << L"Synchronous logging: " << sMsg << Ape::IO::NewLine;} \
		MultiplexD::DaemonInstance::Get()->Logger().Log(Ape::String(L"") + sMsg, ltSeverity); \
	}
*/

#define LOG(sMsg, ltSeverity) \
	{ \
		MultiplexD::DaemonInstance::Get()->Logger().Log(sMsg, ltSeverity); \
	}


#define DEBUG(sMsg) \
	LOG(sMsg, MultiplexD::Logging::ltDebug)
#define NOTICE(sMsg) \
	LOG(sMsg, MultiplexD::Logging::ltNotice)
#define WARN(sMsg) \
	LOG(sMsg, MultiplexD::Logging::ltWarning)
#define ERROR(sMsg) \
	LOG(sMsg, MultiplexD::Logging::ltError)
#define FATAL(sMsg) \
	LOG(sMsg, MultiplexD::Logging::ltFatal)
	

namespace MultiplexD {
	namespace Logging {
		
		enum LoggerSeverity {
			ltTrace = 0x200,
			ltDebug = 0x201,
			ltNotice = 0x202,
			ltWarning = 0x203,
			ltError = 0x204,
			ltFatal = 0x205
		};
		
		class LoggerMessageData : public WorkerModel::MultiplexLetterData {
			TYPE_NAME("MultiplexD::Logging::LoggerMessageData")
		public:
			Ape::String Message;
		};
		
		class Logger : public WorkerModel::MultiplexWorker {
			TYPE_NAME("MultiplexD::Logging::Logger")
		private:
			LoggerSeverity m_LogLevel;
			Ape::IO::FS::Path m_Path;
			Ape::IO::FS::RegularFile m_File;
			bool m_UseStdErr;
		public:
			Logger();
			virtual ~Logger();
			
			void Init();
			void SetLevel(LoggerSeverity ltSeverity);
			
			void Log(const Ape::String& message, LoggerSeverity severity = ltDebug) {
			//void Logger::Log(const Ape::String& message, LoggerSeverity severity) {
				if (severity < m_LogLevel)
					return;
				LoggerMessageData* data = new LoggerMessageData;
				data->Message = L"(" + Ape::DateTime::Current().ToString() + L") " + message;
				WorkerModel::MultiplexLetter letter;
				letter.Data = data;
				letter.LetterType = severity;
				Message(letter);
			}
			
			
			virtual void ProcessMessage(const WorkerModel::MultiplexLetter& letter);
		};
	}
}

#endif // LOGGER_H_INCLUDED
